package ar.uba.fi.tonyvaliente.signature;

/**
 * Representa una funcion de hash generica.
 * Debe ser extendida para poder implementar la
 * generacion del hash.
 * @author dmorello
 */
public abstract class HashFunction {

	private int length;
	
	private int seed;
	
	public HashFunction(int length) {
		this.length = length;
	}

	/**
	 * Setea el máximo número que va a devolver la ejecución de la función.
	 * Debe ser mayor o igual a 64 y potencia de 2.
	 * @param bits
	 */
	public void setLength(int length) throws HashFunctionException{
		if(length < 64 ){ //TODO validar que sea potencia de dos.
			throw new HashFunctionException("La longitud no es válida, debe ser mayor a 64 y potencia de 2");
		}
		
		this.length = length;
	}
	
	/**
	 * @return la mayor número que devolverá esta función.
	 */
	public int getLength(){
		return this.length;
	}
	
	/**
	 * @return el seed utilizado por esta función.
	 */
	public int getSeed() {
		return seed;
	}
	
	/**
	 * modifica el seed con el que trabaja esta función.
	 * Este valor altera los resultados obtenidos al ejecutar la función.
	 * @param seed
	 */
	public void setSeed(int seed) {
		this.seed = seed;
	}
	
	/**
	 * Devuelve el valor de hash para los datos recibidos
	 * por parametro.
	 * @param data Datos a los cuales aplicar la funcion de hash
	 * @return valor de hash de los datos recibidos
	 */
	public abstract Number hash(String data) throws HashFunctionException;
	
	public final int hashCode() {
		return (length + getClass().getName() + seed).hashCode();
	}
	
	public final boolean equals(Object o) {
		if (o == this) return true;
		if (o == null) return false;
		if (o instanceof HashFunction) {
			return equals((HashFunction)o);
		}
		return false;
	}
	
	public final boolean equals(HashFunction f) {
		if (! this.getClass().getName().equals(f.getClass().getName())) {
			return false;
		}
		if (this.getLength() != f.getLength()) {
			return false;
		}
		return this.getSeed() == f.getSeed();
	}
	
	public String toString() {
		return getClass().getName()
			+ "-length:" + length
			+ "-seed:" + seed;
	}

	
}
